package leetcode.pre100;

import java.util.LinkedList;
import java.util.List;
import java.util.Stack;

/**
 * 给定两个整数 n 和 k，返回 1 ... n 中所有可能的 k 个数的组合。
 * <p>
 * 示例:
 * <p>
 * 输入: n = 4, k = 2
 * 输出:
 * [
 * [2,4],
 * [3,4],
 * [2,3],
 * [1,2],
 * [1,3],
 * [1,4],
 * ]
 *
 * @date 2020/6/7 23:16
 */
public class Code77_Combine_组合 {
    public static void main(String[] args) {
        List<List<Integer>> list = combine(4, 2);
        list.forEach(System.out::println);
    }

    public static List<List<Integer>> combine(int n, int k) {
        if (k <= 0) return new LinkedList<>();
        List<List<Integer>> res = new LinkedList<>();
        Stack<Integer> stack = new Stack<>();
        process2(1, n, k, stack, res);
        return res;
    }

    /**
     * 方式1：当前要，当前不要
     */
    private static void process(int i, int n, int k, Stack<Integer> stack, List<List<Integer>> res) {
        if (stack.size() == k) {
            res.add(new LinkedList<>(stack));
            return;
        }
        if (i > n) {
            return;
        }
        //当前要
        stack.push(i);
        process(i + 1, n, k, stack, res);
        stack.pop();
        //当前不要
        process(i + 1, n, k, stack, res);
    }

    /**
     * 方式2：组合
     */
    private static void process2(int i, int n, int k, Stack<Integer> stack, List<List<Integer>> res) {
        if (stack.size() == k) {
            res.add(new LinkedList<>(stack));
            return;
        }
        if (i > n) {
            return;
        }
        for (int j = i; j <= n; j++) {
            stack.push(j);
            process2(j + 1, n, k, stack, res);
            stack.pop();
        }
    }

}
